package 中等.栈;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * 给你一个字符串 path ，表示指向某一文件或目录的 Unix 风格 绝对路径 （以 '/' 开头），
 * 请你将其转化为更加简洁的规范路径。
 * <p>
 * 在 Unix 风格的文件系统中，一个点（.）表示当前目录本身；此外，两个点 （..） 
 * 表示将目录切换到上一级（指向父目录）；两者都可以是复杂相对路径的组成部分。
 * 任意多个连续的斜杠（即，'//'）都被视为单个斜杠 '/' 。 对于此问题，任何其他
 * 格式的点（例如，'...'）均被视为文件/目录名称。
 * <p>
 * 请注意，返回的 规范路径 必须遵循下述格式：
 * <p>
 * 始终以斜杠 '/' 开头。
 * 两个目录名之间必须只有一个斜杠 '/' 。
 * 最后一个目录名（如果存在）不能 以 '/' 结尾。
 * 此外，路径仅包含从根目录到目标文件或目录的路径上的目录（即，不含 '.' 或 '..'）。
 * 返回简化后得到的 规范路径 。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/simplify-path
 */
public class 简化路径_71 {

    public static void main(String[] args) {

        System.out.println(simplifyPath2("/a/../../b/../c//.//c"));

    }

    /**
     * 栈
     * 借助先进后出的特点
     * ..将上一层文件夹出栈，
     * 否则进栈，
     *
     * @param path
     * @return
     */
    public static String simplifyPath(String path) {
        StringBuilder builder = new StringBuilder();
        Deque<String> stack = new ArrayDeque<>();
        String[] paths = path.split("/");
        for (int i = 1; i < paths.length; i++) {  //[, s, , b, a],第一个位置不能用
            if (paths[i].length() == 0 || paths[i].equals(".")) {  //当路径存在//时，数组中多出一个空字符串，.是没有作用的
                continue;
            }
            if (paths[i].equals("..")) {
                if (!stack.isEmpty()) {  //取出上一层文件夹
                    stack.pollFirst();
                }
            } else {
                stack.addFirst(paths[i]);
            }
        }
        if (stack.isEmpty()) {
            return "/";
        }
        while (!stack.isEmpty()) {
            builder.append("/").append(stack.pollLast());
        }
        return builder.toString();
    }

    /**
     * 栈+指针
     * 双指针来找到/-/中间的字符串
     *
     * @param path
     * @return
     */
    public static String simplifyPath2(String path) {
        StringBuilder builder = new StringBuilder();
        Deque<String> stack = new ArrayDeque<>();
        int length = path.length();
        for (int i = 0; i < length; i++) {
            while (i < length && path.charAt(i) == '/') {   //找到不为/的字符
                i++;
            }
            int left = i;
            while (i < length && path.charAt(i) != '/') {  //找到为/的字符，substring方法不包含right边界
                i++;
            }
            int right = i;
            if (right == left) {
                break;
            }
            String curPath = path.substring(left, right);
            if (curPath.equals(".")) {
                continue;
            }
            if (curPath.equals("..")) {
                if (!stack.isEmpty()) {  //取出上一层文件夹
                    stack.pollFirst();
                }
            } else {
                stack.addFirst(curPath);
            }
        }
        if (stack.isEmpty()) {
            return "/";
        }
        while (!stack.isEmpty()) {
            builder.append("/").append(stack.pollLast());
        }
        return builder.toString();
    }

}
